﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Algorithm_api.calculate.FractalTree
{
    public class FractalTree
    {
        public double angle { get; set; }
        public double length { get; set; }
        public int deep { get; set; }
        public int BranchNumber { get; set; } = 2;
        public double c_len { get; set; } = 2.0 / 3.0;
        public List<Line> tree { get; set; } = new List<Line>();

        public FractalTree(double angle,double length,int deep)
        {
            this.angle = Math.PI / (180 / angle);
            this.length = length;
            this.deep = deep;
        }

        public List<Line> GetTree(Line start)
        {
            GetTree(start, angle, deep);
            tree.Add(start);
            return tree;
        }

        public void GetTree(Line p,double angle,int deep)
        {
            if (deep == 0) return;
            double length = GetPointLength(p);
            var children = GetNextLine(p, angle,length);
            tree.AddRange(children);
            GetTree(children[1], angle - this.angle, deep - 1);
            GetTree(children[0], angle + this.angle, deep - 1);
        }

        public double GetPointLength(Line p)
        {
            double l = (p.x1 - p.x2) * (p.x1 - p.x2) + (p.y1 - p.y2) * (p.y1 - p.y2);
            return Math.Sqrt(l);
        }

        public List<Line> GetNextLine(Line l,double angle,double length)
        {
            List<Line> children = new List<Line>();
            double n_length = length * c_len;
            double x1 = l.x1 + (l.x2 - l.x1) / 3.0;
            double y1 = l.y1 - (l.y1 - l.y2) / 3.0;
            double x2 = x1 + Math.Cos(Math.PI / 2 - angle) * n_length;
            double y2 = y1 - Math.Sin(Math.PI / 2 - angle) * n_length;
            


            double x3 = l.x1 + (l.x2 - l.x1) / 3.0 * 2;
            double y3 = l.y1 - (l.y1 - l.y2) / 3.0 * 2;
            double x4 = x3 - Math.Sin(Math.PI / 2 - angle) * n_length;
            double y4 = y3 - Math.Cos(Math.PI / 2 - angle) * n_length;

            children.Add(new Line(x1, y1, x2, y2));
            children.Add(new Line(x3, y3, x4, y4));
            return children;
        }
    }
}
